<template>
  <!-- 
    实现表单验证
    1. 设置 , 在el-input 设置name属性, type属性绑定
    2. 在form全局设置rules表单验证规则
    3. 在需要验证的字段 使用props绑定到form-item上

    表单验证流程为, el-form的model 对应 input的v-modal 选择是使用prop设置 当前el-form-item的model

    rules 为对象, 每个key表示一个inputModel验证的对象, 里面是数组, 每个规则返回的message
    所以我需要制作一个rules模块, 将表单验证的规则放在里面, 然后通过form将需要验证的规则筛选出来
  -->

  <ElForm v-if="formData" ref="blogForm" class="blog-modal--form" :model="form">
    <ElFormItem
      v-for="formItem of formData"
      :key="formItem.query"
      class="blog-form--item"
      :label="formItem.lable"
      label-width="20%"
      :prop="formItem.query"
      :rules="rulesData[formItem.query]"
    >
      <ElUpload
        v-if="formItem.query === 'avatar'"
        ref="uploadPic"
        class="avatar-uploader"
        :action="action"
        name="1"
        :headers="{ Authorization: `Bearer ${user.token}` }"
        :show-file-list="false"
        :on-success="handleAvatarSuccess"
        :before-upload="beforeAvatarUpload"
      >
        <ElAvatar v-if="form[formItem.query]" :src="form[formItem.query]" shape="square" :size="100" />
        <i v-else class="blog-upload--avatar el-icon-plus avatar-uploader-icon" />
      </ElUpload>
      <ElInput
        v-if="formItem.query !== 'avatar'"
        :id="formItem.inputName"
        v-model="form[formItem.query]"
        autocomplete="off"
        :disabled="formItem.readonly"
        :name="formItem.query"
        :type="formItem.inputType"
      />
    </ElFormItem>
  </ElForm>
</template>

<script setup lang="ts">
import { ElForm, ElNotification, ElUpload } from 'element-plus'
import { ref, computed, watch, defineProps } from 'vue'

import { formUpload } from '@/config'
import FORM_DATA from '@/config/form.config'
import RULES_DATA from '@/config/rule.config'
import { useModal } from '@/store/modal'
import { useUser } from '@/store/user'

import type { FormType } from '@/config/form.config'
let props = defineProps<{
  type: string
}>()
let user = useUser()
let modal = useModal()
let form = ref<any>({})
let blogForm = ref<typeof ElForm | null>()
let uploadPic = ref<typeof ElUpload | null>()
let formData = computed<FormType[]>(() => {
  return FORM_DATA[props.type]
})
let rulesData = computed(() => {
  return RULES_DATA
})
let action = ref<string>(formUpload)
watch(
  () => modal.isShow,
  (newValue) => {
    if (!newValue) {
      infoFormValue()
      infoForm()
    }
  },
)
function infoFormValue() {
  blogForm.value?.resetFields()
}
function infoForm() {
  form.value = {}
}

function handleAvatarSuccess(result) {
  form.value.avatar = result.data[0]?.fileUrl
}

function beforeAvatarUpload(file) {
  // 在上传前验证文件, 是否是image, 是否size < 5m
  // 全部判断一遍
  let isPass = /image/g.test(file.type) && file.size < 5 * 1024 * 1024
  if (!isPass) {
    let message = /image/g.test(file.type) ? '图片大小不能大于5MB' : '请上传图片哦'
    ElNotification.error({
      title: '上传失败',
      message,
      type: 'error',
    })
    uploadPic.value?.abort?.(file)
    // return false, 才能阻止upload上传
    return false
  }
}

defineExpose({
  form,
  blogForm,
})
</script>
<style lang="stylus" scoped>
.blog-form--item {
  margin-right: 20%;
}
.blog-upload--avatar
  width 80px;
  height 80px
  line-height 80px
  text-align center
  font-size 32px
  box-shadow 0 0 6px #ccc
</style>
